<html>
<head><meta charset="utf-8"><title>What allows AddAssign to get multiple references to a Vec? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html">What allows AddAssign to get multiple references to a Vec?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="197164948"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197164948" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197164948">(May 11 2020 at 15:47)</a>:</h4>
<p>This works:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">];</span><span class="w"></span>
<span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span><span class="w"></span>
</code></pre></div>


<p>What special knowledge exists to allow this? I would have thought that this would result in a "cannot borrow ... as immutable because it is also borrowed as mutable" error. And replacing the number with a newtype <em>does</em> result in that error. This makes me think there's some built-in implementation for <code>Vec</code> / <code>AddAssign</code> / <code>i32</code> or some combination.</p>



<a name="197165456"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197165456" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197165456">(May 11 2020 at 15:51)</a>:</h4>
<p>I'm pretty sure you're not getting two &amp;mut references there?</p>



<a name="197165586"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197165586" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197165586">(May 11 2020 at 15:52)</a>:</h4>
<p>based on the MIR it looks like that desugars into roughly speaking:</p>
<div class="codehilite"><pre><span></span><code>let mut a = vec![0, 1];
let mut p0 = &amp;mut a[0];
let p1 = a[1];
*p0 += p1;
</code></pre></div>



<a name="197165613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197165613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197165613">(May 11 2020 at 15:52)</a>:</h4>
<p>and that works because of 2 phase borrows letting the <code>&amp;mut </code> kick in "late"</p>



<a name="197165674"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197165674" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197165674">(May 11 2020 at 15:53)</a>:</h4>
<p>I had a feeling 2pb would be involved, so maybe the question is why doesn't 2pb kick in for the newtype version?</p>



<a name="197165695"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197165695" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197165695">(May 11 2020 at 15:53)</a>:</h4>
<p>hm, is your newtype Copy?</p>



<a name="197165705"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197165705" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197165705">(May 11 2020 at 15:53)</a>:</h4>
<p><a href="https://stackoverflow.com/q/61732690/155423">https://stackoverflow.com/q/61732690/155423</a></p>



<a name="197165713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197165713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197165713">(May 11 2020 at 15:53)</a>:</h4>
<p>It is</p>



<a name="197166377"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166377" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166377">(May 11 2020 at 15:57)</a>:</h4>
<p>Seems weird as <code>Vec</code> is not a lang item...</p>



<a name="197166520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166520">(May 11 2020 at 15:58)</a>:</h4>
<p>here's a theory: the add no longer happens "in the compiler"</p>



<a name="197166574"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166574" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166574">(May 11 2020 at 15:58)</a>:</h4>
<p>I was also wondering if <code>AddAssign</code> is a compiler builtin or something</p>



<a name="197166621"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166621" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166621">(May 11 2020 at 15:59)</a>:</h4>
<p>And maybe <code>Vec</code> decays to a slice</p>



<a name="197166640"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166640" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166640">(May 11 2020 at 15:59)</a>:</h4>
<p>here's a diff of the mir <a href="https://gist.github.com/Mark-Simulacrum/93386e15a03cd562bdaf9c95dff900b0">https://gist.github.com/Mark-Simulacrum/93386e15a03cd562bdaf9c95dff900b0</a></p>



<a name="197166643"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166643" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166643">(May 11 2020 at 15:59)</a>:</h4>
<p>still inspecting it</p>



<a name="197166662"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166662" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166662">(May 11 2020 at 15:59)</a>:</h4>
<p>So between that, we end up completely in language space, not in library space.</p>



<a name="197166932"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166932" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166932">(May 11 2020 at 16:01)</a>:</h4>
<p>hm actually it almost looks like the indexing order switched?</p>



<a name="197166969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197166969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197166969">(May 11 2020 at 16:01)</a>:</h4>
<p>so the <code>mut</code> happens first?</p>



<a name="197167089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197167089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197167089">(May 11 2020 at 16:02)</a>:</h4>
<p>so there is this <a href="https://github.com/rust-lang/rust/pull/47489/files#diff-b3d7798e2a3c43eca68203216e36de65R544">https://github.com/rust-lang/rust/pull/47489/files#diff-b3d7798e2a3c43eca68203216e36de65R544</a> but not sure if it's still the case</p>



<a name="197167199"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197167199" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197167199">(May 11 2020 at 16:02)</a>:</h4>
<p>And <a href="https://github.com/rust-lang/rust/issues/49434">this</a>:</p>
<blockquote>
<p>In practice, this covers the following cases:<br>
-    binary assignment operators (+=, -=, *=, etc.) Note this does /not/ include IndexMut operations at this time</p>
</blockquote>



<a name="197167349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197167349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197167349">(May 11 2020 at 16:03)</a>:</h4>
<p>but yeah the MIR for the newtype has IndexMut happening first, which activates the 2 phase borrow (if you can even call it that since there's not really 2 phases)</p>



<a name="197167436"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197167436" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197167436">(May 11 2020 at 16:04)</a>:</h4>
<p>You wanna write that up as an answer?</p>



<a name="197167456"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197167456" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197167456">(May 11 2020 at 16:04)</a>:</h4>
<p>nah that would require more time than I have :)</p>



<a name="197170648"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197170648" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197170648">(May 11 2020 at 16:27)</a>:</h4>
<p>What flags did you use to get the MIR before the borrow checker said "stop doing that"?</p>



<a name="197171263"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20allows%20AddAssign%20to%20get%20multiple%20references%20to%20a%20Vec%3F/near/197171263" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20allows.20AddAssign.20to.20get.20multiple.20references.20to.20a.20Vec.3F.html#197171263">(May 11 2020 at 16:31)</a>:</h4>
<p>Ah, I see <a href="https://stackoverflow.com/questions/61732690/why-is-it-allowed-to-have-both-immutable-and-mutable-borrows-of-a-vector-of-nume#comment109198269_61734260">you commented</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>